//
//  StickKeyboardInput.swift
//  xmall
//
//  Created by zhuxietong on 2020/2/16.
//  Copyright © 2020 xmall. All rights reserved.
//

import Foundation
import Eelay
import UIKit
//import TXLiteAVSDK_Professional
import AsyncDisplayKit


extension StickKeyboardInput:UITextViewDelegate{
    
    public func textViewDidChange(_ textView: UITextView) {
        
//        let rect = textView.contentSize
//        let height = rect.height
//        if height >= max_text_height
//        {
//            textView.isScrollEnabled = true
//
//        }else{
//            textView.isScrollEnabled = false
//        }
    }
}


open class StickKeyboardInput: NSObject{
    public class Input:UITextView{
        public override var frame: CGRect{
            didSet{
            }
        }
    }

    public var max_text_height:CGFloat = 58
    public var height:CGFloat = 0;
    public var isEnabled = true
    
    public var changeKeyboardHeight:(_:CGFloat)->Void = {_ in}
    public var changeInputFrame:(_:CGRect)->Void = {_ in}
    
    public var changeAppear:(_:AppearStatus)->Void = {_ in}

    public struct ChatBarStyle{
        public struct textView {
            public static let borderColor = UIColor(shex: "#bbbbbb44")
            public static let textColor = UIColor._foreground
            public static let font = UIFont.systemFont(ofSize: 17)
            public static let radius:CGFloat = 5.0
            public static let backColor = UIColor(shex: "#eeeeee44")
        }
        
        public struct seperator {
            public static var color = UIColor(shex: "#cccccc")
        }
    }
    public var needMask = true
    public var input =  Input(frame: [0])
    public var maskView = UIButton()
    public var bottom = NSLayoutConstraint()
    
    public var _container:UIView? = nil
    public var container:UIView?{
        get{
            if let c = _container{
                return c
            }
            return window
        }set{
            _container = newValue
            if let n = newValue{
                configContainer(view: n)
            }
        }
    }
    open func configContainer(view:UIView){
        
    }
    open var window:UIView?{
        get{
            var back:UIView? = UIApplication.shared.keyWindow
            if back == nil{
                back = UIApplication.shared.keyWindow?.rootViewController?.view
            }
            return back
        }
    }
    
    
    
    open func didInit(){
        weak var wself = self
        co_delay(delay: 0.2) {
            wself?.addLayRules()
        }
    }

    public override init() {
        super.init();
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardChange(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardChange(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardChange(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardChange(_:)), name: UIResponder.keyboardDidChangeFrameNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardChange(_:)), name: UIResponder.keyboardDidHideNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardChange(_:)), name: UIResponder.keyboardDidShowNotification, object: nil)

        didInit()
       
    }
  
    open func layTextView(textView:UITextView) {
        textView.setContentConstrainToHighLever()
        textView.isScrollEnabled = false
        
        if #available(iOS 13.0, *) {
            let blur = UIVisualEffectView(effect: UIBlurEffect(style: .systemThinMaterial))
            backV.eelay = [
                [blur,[ee.T.L.B.R,[0,0,100,0]]],
            ]
        } else {
            let blur = UIVisualEffectView(effect: UIBlurEffect(style: .light))
            backV.eelay = [
                [blur,[ee.T.L.B.R,[0,0,100,0]]],
            ]

            // Fallback on earlier versions
        }
        
        backV.clipsToBounds = false
        backV.eelay = [
            [textView,.<"\(max_text_height)",[ee.T.L.B.R,[8.+1000,10.+1000,-8.+1000,-10.+1000]]]
        ]
    }
    
    
    public var currentFrame:CGRect = .zero{
        didSet{
            changeInputFrame(currentFrame)
        }
    }
    
    public func checkFrame() {
        let frame = backV.frame
        if (frame != currentFrame){
            currentFrame = frame
        }
    }
    


    
    public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        let rect = textView.contentSize
        let height = rect.height
        if height >= max_text_height
        {
            if (!textView.isScrollEnabled){
                textView.isScrollEnabled = true
            }
        }else{
            if (textView.isScrollEnabled){
                textView.isScrollEnabled = false
            }
        }
      
        if text == "\n"{
            if (textView.text.len > 0){
                self.doneInput(textView.text)
//                textView.text = ""
                textView.setNeedsLayout()
                textView.layoutIfNeeded()
            }
            else
            {
                textView.resignFirstResponder()
            }
            return false
        }else{
            weak var wself = self
            co_delay(delay: 0.02) {
                wself?.checkFrame()
            }
                  
        }
        return true
    }
    
    public let backV = UIView()
    
    @discardableResult
    open func becomeFirstResponder() -> Bool {
        guard let v = container else {return false}
        if (needMask){
            mask_constains = v.setEeLays(lays: [
                [maskView,[ee.T.L.B.R]]
            ]).1
        }
        constains = v.setEeLays(lays: [
            [backV,[ee.B,ee.B,0.+1000],[ee.L.R,[0.+1000,0.+1000]]]
        ]).1
        weak var ws = self
        co_delay(delay: 0.02) {
            ws?.checkFrame()
        }
        changeAppear(.willAppear)
        return input.becomeFirstResponder()
    }
    
    @objc @discardableResult
    public func resignFirstResponder() -> Bool {
        return input.resignFirstResponder()
    }
    
    open func removeViews(){
        backV.removeFromSuperview()
        container?.removeConstraints(constains)
        constains.removeAll()
        maskView.removeFromSuperview()
        container?.removeConstraints(mask_constains)
        mask_constains.removeAll()
    }
    
    public var constains = [NSLayoutConstraint]()
    public var mask_constains = [NSLayoutConstraint]()

    public var bottomC:NSLayoutConstraint?{
        get{
            return constains.first
        }
    }
    
    
    
    
    
    open  func initStyle(){
        backV.bsui.background(hex: "#e1e1e100")
       input.bsui.background(color: ChatBarStyle.textView.backColor).set(radius: ChatBarStyle.textView.radius, width: 0.5, color: ChatBarStyle.textView.borderColor)
       input.delegate = self
       input.backgroundColor = ChatBarStyle.textView.backColor
       input.font = ChatBarStyle.textView.font
       input.textColor = ChatBarStyle.textView.textColor
       input.returnKeyType = .send
        maskView.addTarget(self, action: #selector(resignFirstResponder), for: .touchDown)
//       maskView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(resignFirstResponder)))
       backV.alpha = 0
       backV.isUserInteractionEnabled = false
    }
    open func addLayRules() {
       
       
        
        initStyle()
        layTextView(textView: input)
        guard let v = container else {return}
        constains = v.setEeLays(lays: [
            [backV,[ee.B,ee.B,0.+1000],[ee.L.R,[0.+1000,0.+1000]]]
        ]).1

        weak var wself = self
        co_delay(delay: 0.1) {
            if let ws = wself{
                ws.bottom_just_distance = ws.backV.frame.size.height
                ws.backV.removeFromSuperview()
                v.removeConstraints(ws.constains)
                ws.backV.alpha = 1
                ws.backV.isUserInteractionEnabled = true
                
            }
        }
    }
    
    public var bottom_just_distance:CGFloat = 0
    
    @objc public func keyboardChange(_ notify:Notification)
    {
        let userInfo = notify.userInfo
//        var animationDuration:TimeInterval = 0.25
        var keyboardEndFrame:CGRect = CGRect(x: 0, y: 0, width: 0, height: 0)
        let animationDuration_v = userInfo![UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
        _ = userInfo![UIResponder.keyboardAnimationCurveUserInfoKey] as! Int

        _ = animationDuration_v as TimeInterval
        keyboardEndFrame = (userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
        _ = keyboardEndFrame.size.height
        let h = keyboardEndFrame.size.height
        switch notify.name {
        case UIResponder.keyboardWillShowNotification,UIResponder.keyboardWillChangeFrameNotification:
            checkEditContainer()
            guard let oldH = bottomC?.constant else {return}
            if (oldH == h){return}

           
//            UIView.beginAnimations(nil, context: nil)
//            UIView.setAnimationDuration(animationDuration)
//            UIView.setAnimationCurve(UIView.AnimationCurve.init(rawValue: curve) ?? .easeIn)
//
//            print("++++++++SIIII\(h)")
            bottomC?.constant = -h
            backV.setNeedsLayout()
            backV.layoutIfNeeded()
            container?.setNeedsLayout()
            container?.layoutIfNeeded()
//            UIView.commitAnimations()
            changeKeyboardHeight(h)

        case UIResponder.keyboardWillHideNotification:
            changeAppear(.willDisappear)
            guard let oldH = bottomC?.constant else {return}
            if (oldH == h){return}
                
//            UIView.beginAnimations(nil, context: nil)
//            UIView.setAnimationDuration(animationDuration)
//            UIView.setAnimationCurve(UIView.AnimationCurve.init(rawValue:curve) ?? .easeIn)

            bottomC?.constant = bottom_just_distance
            backV.setNeedsLayout()
            backV.layoutIfNeeded()
            maskView.alpha = 0
            container?.setNeedsLayout()
            container?.layoutIfNeeded()
//            UIView.commitAnimations()
            self.currentFrame = .zero
            changeKeyboardHeight(0)
           
        case UIResponder.keyboardDidHideNotification:
            removeViews()
        default: break
            
        }
    }
    
    open func checkEditContainer(){
        
    }
    
    
    public var doneInput:(_:String)->Void = {_ in}

    
}
